import torch
import torch.nn as nn
import numpy as np

# 定义样本数量和类别数量
num_samples = 4
num_classes = 3

# 模拟模型输出
logits = torch.randn(num_samples, num_classes, requires_grad=True)
# 模拟真实标签
targets = torch.randint(0, num_classes, (num_samples,))
# 将标签进行 One - Hot 编码
targets_one_hot = nn.functional.one_hot(targets, num_classes=num_classes).float()

# 使用 PyTorch 的 BCELoss 计算损失
probabilities = torch.sigmoid(logits)
criterion = nn.BCELoss()
pytorch_loss = criterion(probabilities, targets_one_hot)
print(f"PyTorch BCELoss 计算的损失: {pytorch_loss.item()}")

# 将 PyTorch 张量转换为 NumPy 数组
logits_np = logits.detach().numpy()
targets_one_hot_np = targets_one_hot.numpy()

# 使用 NumPy 手动计算 sigmoid 函数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

probabilities_np = sigmoid(logits_np)

# 手动实现 BCELoss 计算
def bceloss_numpy(y_true, y_pred):
    epsilon = 1e-15
    y_pred = np.clip(y_pred, epsilon, 1 - epsilon)
    return -np.mean(y_true * np.log(y_pred) + (1 - y_true) * np.log(1 - y_pred))

numpy_loss = bceloss_numpy(targets_one_hot_np, probabilities_np)
print(f"NumPy 手动计算的损失: {numpy_loss}")
    